package cn.hnh.controller;

import cn.hnh.constrant.Constrants;
import cn.hnh.expection.OutofstockException;
import cn.hnh.expection.RepeatKillExpection;
import cn.hnh.pojo.Goods;
import cn.hnh.pojo.Order;
import cn.hnh.pojo.User;
import cn.hnh.utils.JsonUtils;
import cn.hnh.utils.RedisUtils;
import cn.hnh.service.GoodsService;
import cn.hnh.vo.ResultVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Date;
import java.util.UUID;

@RestController
public class SeckillController {

    private static final String Lock_Key="Lock_key";
    private static final long Timeout=10;
    @Autowired
    private GoodsService goodsService;
    @Autowired
    private RedisUtils redisUtils;

    @RequestMapping("/{goodid}/seckill")
    public  ResultVo execute_seckill(@PathVariable("goodid") int goodid,int userid) {
        String uuid= UUID.randomUUID().toString();
        //redis分布式锁
        boolean lock = redisUtils.lock(Lock_Key,uuid,Timeout);
        if (!lock) {
            return new ResultVo(false, "秒杀失败");
        }
        try {
            //从redis缓存中获取商品信息
            Goods goods = (Goods) JsonUtils.toObject((String) redisUtils.get(Constrants.Good_Prefix + goodid), Goods.class);
            if (goods == null) {
                goods = goodsService.FindById(goodid);
                redisUtils.set(Constrants.Good_Prefix + goodid, JsonUtils.toJson(goods));
                redisUtils.set(Constrants.Good_Stock + goodid, goods.getStock());
            }
            int stock = (int) redisUtils.get(Constrants.Good_Stock + goodid);
            if (stock > 0) {
                try {
                    boolean res = goodsService.ExecuteKill(new Order(userid, goodid, new Date(), goods.getMoney()));
                    if (res)
                        redisUtils.decr(Constrants.Good_Stock + goodid, 1);   //减少redis中的库存
                } catch (RepeatKillExpection e) {
                    return new ResultVo(false, "重复秒杀!");
                } catch (OutofstockException e) {
                    return new ResultVo(false, "库存不足!");
                } catch (Exception e) {
                    return new ResultVo(false, "秒杀失败!");
                }
            } else
                return new ResultVo(false, "库存不足!");
            }catch (Exception e) {
            e.printStackTrace();
        } finally {
            redisUtils.unlock(Lock_Key,uuid);
        }
       return new ResultVo(true,"秒杀成功!");
    }

}
